package com.rxh.risk;

import com.rxh.cache.RiskLimitCache;
import com.rxh.cache.SysConstantCache;
import com.rxh.exception.PayException;
import com.rxh.pojo.core.CoreCardholder;
import com.rxh.pojo.core.CoreOrder;
import com.rxh.pojo.core.CoreOrderDetail;
import com.rxh.pojo.risk.RiskLimit;
import com.rxh.pojo.sys.SysConstant;
import com.rxh.utils.SystemConstant;
import com.rxh.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.sql.Timestamp;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: 陈俊雄
 * Date: 2018/9/10
 * Time: 10:06
 * Project: Management
 * Package: com.rxh.risk
 */
@Component
public class LimitComponent implements RiskInterface{

    @Autowired
    private RiskLimitCache riskLimitCache;

    @Autowired
    private SysConstantCache sysConstantCache;

    @Override
    public void analysis(RiskContext riskContext) throws PayException {
        Integer webSiteId = riskContext.getMerchantWebSite().getId();
        Integer merId = riskContext.getTradeObject().getMerNo();
        Integer acquirerId = riskContext.getCoreAcquirer().getId();
        List<SysConstant> elements = sysConstantCache.getConstantByGroupName(SystemConstant.RISK_LIMIT);
        List<RiskLimit> limitList = riskLimitCache.getLimit(webSiteId,merId,acquirerId,elements);
        for (RiskLimit riskLimit : limitList) {
            SysConstant sysConstant = sysConstantCache.getSysConstantByid(riskLimit.getElement());
            //CoreOrder coreOrder = limitParam(riskLimit, webSiteId, merId, acquirerId);
            //coreOrder.setTradeTime(getTimeOffHours(riskLimit.getCtyle() * -1));
            CoreOrder coreOrder = getCoreOrderParam(riskLimit,sysConstant,riskContext);
            //Map<String, String> map = getMap(sysConstant.getFirstValue(), riskContext, riskLimit);
            List<Map<String, Object>> limitCount = getCounts(coreOrder,sysConstant,riskLimit,riskContext);
            for (Map<String, Object> limitMap : limitCount) {
                if (!limitMap.isEmpty()) {
                    switch (Short.valueOf(limitMap.get("bank_status").toString())) {
                        case 0:
                            if (Integer.valueOf(limitMap.get("status_count").toString()) > 0 && Integer.valueOf(limitMap.get("status_count").toString()) >= riskLimit.getElementValue()) {
                                throw new PayException( "风控元素 \"" + sysConstant.getName() + " \" : 超过成功次数 " + riskLimit.getElementValue(),2003);
                            }
                            break;
                        case 1:
                            if (Integer.valueOf(limitMap.get("status_count").toString()) > 0 && Integer.valueOf(limitMap.get("status_count").toString()) >= riskLimit.getElementFailValue()) {
                                throw new PayException( "风控元素 \"" + sysConstant.getName() + " \" : 超过失败次数 " + riskLimit.getElementValue(),2003);
                            }
                            break;
                        default:
                            break;
                    }
                }
            }
        }
    }

    // /**
    //  * 根据reftype设置iD
    //  * @param riskLimit
    //  * @param webSiteId
    //  * @param merId
    //  * @param acquirerId
    //  * @return
    //  */
    // private CoreOrder limitParam(RiskLimit riskLimit,Integer webSiteId,Integer merId,Long acquirerId) {
    //     CoreOrder coreOrder = new CoreOrder();
    //     switch (riskLimit.getRefType()) {
    //         case 0:
    //             break;
    //         case 1:
    //             coreOrder.setAccountId(acquirerId);
    //             break;
    //         case 2:
    //             coreOrder.setMerId(merId);
    //             break;
    //         case 3:
    //             coreOrder.setSiteId(webSiteId);
    //             break;
    //         default:
    //             break;
    //     }
    //     return coreOrder;
    // }


    // /**
    //  * 获取交易参数
    //  * @param tableName
    //  * @param riskContext
    //  * @param riskLimit
    //  * @return
    //  */
    // private static Map<String,String> getMap(String tableName,RiskContext riskContext,RiskLimit riskLimit) {
    //     Map<String,String> result = new HashMap<String, String>();
    //     if (StringUtils.equals(SystemConstant.LIMIT_TABLE_CARDHOLDER, tableName)) {
    //         result.put("first_name",riskContext.getTradeObject().getBillFirstName());
    //         result.put("last_name",riskContext.getTradeObject().getBillLastName());
    //         result.put("country",riskContext.getTradeObject().getBillCountry());
    //         result.put("province",riskContext.getTradeObject().getBillState());
    //         result.put("city",riskContext.getTradeObject().getBillCity());
    //         result.put("address",riskContext.getTradeObject().getBillAddress());
    //         result.put("zip",riskContext.getTradeObject().getBillZip());
    //         result.put("email",riskContext.getTradeObject().getBillEmail());
    //         result.put("phone",riskContext.getTradeObject().getBillPhone());
    //         result.put("md5",riskContext.getCardholder().getMd5());
    //         result.put("account_id",riskContext.getCoreAcquirer().getId().toString());
    //     } else if (StringUtils.equals(SystemConstant.LIMIT_TABLE_RECIPIENTS,tableName)) {
    //         result.put("first_name",riskContext.getTradeObject().getShipFirstName());
    //         result.put("last_name",riskContext.getTradeObject().getShipLastName());
    //         result.put("country",riskContext.getTradeObject().getShipCountry());
    //         result.put("province",riskContext.getTradeObject().getShipState());
    //         result.put("city",riskContext.getTradeObject().getShipCity());
    //         result.put("address",riskContext.getTradeObject().getShipAddress());
    //         result.put("zip",riskContext.getTradeObject().getShipZip());
    //         result.put("phone",riskContext.getTradeObject().getShipPhone());
    //         result.put("ip",riskContext.getTradeObject().getIp());
    //         result.put("account_id",riskContext.getCoreAcquirer().getId().toString());
    //
    //     } else if (StringUtils.equals(SystemConstant.LIMIT_TABLE_ORDER,tableName)) {
    //         switch (riskLimit.getElement()) {
    //             case SystemConstant.LIMIT_MER_ORDER_ID:
    //                 result.put("mer_order_id",String.valueOf(riskContext.getTradeObject().getBillNo()));
    //                 break;
    //             case SystemConstant.LIMIT_MER_ID:
    //                 result.put("mer_id",String.valueOf(riskContext.getTradeObject().getMerNo()));
    //                 break;
    //             case SystemConstant.LIMIT_MER_WEBSET:
    //                 result.put("site_id",String.valueOf(riskContext.getMerchantWebSite().getId()));
    //                 break;
    //                 default:
    //                     break;
    //         }
    //     }
    //     return result;
    // }
    private CoreOrder getCoreOrderParam(RiskLimit riskLimit,SysConstant sysConstant,RiskContext riskContext) {
        CoreOrder coreOrder = new CoreOrder();
        if (StringUtils.equals(SystemConstant.LIMIT_TABLE_ORDER,sysConstant.getFirstValue())) {
            switch (riskLimit.getElement()) {
                case SystemConstant.LIMIT_MER_ORDER_ID:
                    coreOrder.setMerOrderId(riskContext.getTradeObject().getBillNo());
                    break;
                case SystemConstant.LIMIT_MER_ID:
                    coreOrder.setMerId(riskContext.getTradeObject().getMerNo());
                    break;
                case SystemConstant.LIMIT_MER_WEBSET:
                    coreOrder.setSiteId(riskContext.getMerchantWebSite().getId());
                    break;
                default:
                    break;
            }
            if (riskLimit.getRefType() == 1) coreOrder.setAccountId(riskContext.getCoreAcquirer().getId());
        }
        coreOrder.setTradeTime(getTimeOffHours(riskLimit.getCtyle() * -1));
        return coreOrder;
    }

    /**
     * 获取当前时间
     * @param hours
     * @return
     */
    private Timestamp getTimeOffHours(int hours) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR_OF_DAY,hours);
        return new Timestamp(calendar.getTimeInMillis());
    }

    private  List<Map<String,Object>> getCounts(CoreOrder coreOrder,SysConstant sysConstant,RiskLimit riskLimit,RiskContext riskContext) {
        List<Map<String,Object>> totalMap =  new ArrayList<Map<String,Object>>();
            if (StringUtils.equals(SystemConstant.LIMIT_TABLE_ORDER,sysConstant.getFirstValue())) {
            totalMap = riskLimitCache.getCountCoreOrder(coreOrder);
        } else if (StringUtils.equals(SystemConstant.LIMIT_TABLE_CARDHOLDER, sysConstant.getFirstValue())) {
            CoreCardholder coreCardholder = new CoreCardholder();
            switch (riskLimit.getElement()) {
                case SystemConstant.LIMIT_CARDNO:
                    coreCardholder.setMd5(riskContext.getCardholder().getMd5());
                    break;
                case SystemConstant.LIMIT_EMAIL:
                    coreCardholder.setEmail(riskContext.getTradeObject().getBillEmail());
                    break;
                case SystemConstant.LIMIT_PHONE:
                    coreCardholder.setPhone(riskContext.getTradeObject().getBillPhone());
                    break;
                default:
                    break;
            }
            totalMap = riskLimitCache.getCountCoreCardHolder(coreOrder,coreCardholder);
        } else if (StringUtils.equals(SystemConstant.LIMIT_TABLE_RECIPIENTS,sysConstant.getFirstValue())){
            CoreOrderDetail coreOrderDetail = new CoreOrderDetail();
            switch (riskLimit.getElement()) {
                case SystemConstant.LIMIT_IP:
                    coreOrderDetail.setIp(riskContext.getTradeObject().getIp());
                    break;
                case SystemConstant.LIMIT_ADDRESS:
                    coreOrderDetail.setAddress(riskContext.getTradeObject().getShipAddress());
                    coreOrderDetail.setCountry(riskContext.getTradeObject().getShipCountry());
                    coreOrderDetail.setCity(riskContext.getTradeObject().getShipCity());
                    coreOrderDetail.setProvince(riskContext.getTradeObject().getShipState());
                    break;
                default:
                    break;
            }
            totalMap = riskLimitCache.getCountCardHolderId(coreOrder,coreOrderDetail);
        }
        return totalMap;
    }


    @Override
    public String getRiskName() {
        return SystemConstant.RISK_LIMIT;
    }

}
